package es.uc3m.setichat.utils.setichatxmlschema;

import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

import es.uc3m.setichat.appengine.servlets.CreateSetiChatMessageException;
import es.uc3m.setichat.constants.ErrorConstants;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.Certificaterequest;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.ContactList;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.ContactList.Contact;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.Download;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.MobileList;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.Response;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.Signup;
import es.uc3m.setichat.utils.setichatxmlschema.SetiChatMessage.Content.Upload;

public class SetiChatMessageFactory extends SetiChatMessage {
	ObjectFactory factory;
    // pppp
	public SetiChatMessageFactory() {
		factory = new ObjectFactory();
	}

	/**
	 * 
	 * */
	public SetiChatMessage createSetiChatMessage(String xmlSetiChatMessage)
			throws CreateSetiChatMessageException {
		JAXBContext jc = null;
		SetiChatMessage setiChatMessage = null;
		try {
			jc = JAXBContext
					.newInstance("es.uc3m.setichat.utils.setichatxmlschema");
			Unmarshaller u = jc.createUnmarshaller();
			StringBuffer xmlStr = new StringBuffer(xmlSetiChatMessage);
			setiChatMessage = (SetiChatMessage) u.unmarshal(new StreamSource(
					new StringReader(xmlStr.toString())));
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		if (setiChatMessage == null) {
			throw new CreateSetiChatMessageException(
					ErrorConstants.ERROR_CODE_WRONG_FORMAT);
		}
		return setiChatMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageSignup(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, String nick, String mobile) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Signup signup = this.factory.createMessageContentSignup();
		signup.setNick(nick);
		signup.setMobile(mobile);

		Content content = this.factory.createMessageContent();
		content.setSignup(signup);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageContactRequest(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, ArrayList<String> mobileArrayList) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		MobileList mobileList = factory.createMessageContentMobileList();
		for (String mobible : mobileArrayList) {
			mobileList.getMobile().add(mobible);
		}

		Content content = this.factory.createMessageContent();
		content.setMobileList(mobileList);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageContactResponse(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed,
			ArrayList<String> mobileArrayList, ArrayList<String> nickArrayList) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		ContactList contactList = factory.createMessageContentContactList();
		for (int i = 0; i < mobileArrayList.size(); i++) {
			Contact contact = new Contact();
			contact.setMobile(mobileArrayList.get(i));
			contact.setNick(nickArrayList.get(i));
			contactList.getContact().add(contact);
		}

		Content content = this.factory.createMessageContent();
		content.setContactList(contactList);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageChatMessage(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, String chatMessage) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Content content = this.factory.createMessageContent();
		content.setChatMessage(chatMessage);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageConnect(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Content content = this.factory.createMessageContent();
		content.setConnection(new String());

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageResponse(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, String responseCode,
			String responseMessage) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Response response = factory.createMessageContentResponse();
		response.setResponseCode(responseCode);
		response.setResponseMessage(responseMessage);

		Content content = this.factory.createMessageContent();
		content.setResponse(response);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageRevocation(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, String mobile) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Content content = this.factory.createMessageContent();
		content.setRevokedMobile(mobile);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageCertificateRequest(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, String typeCert, String mobile) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Certificaterequest certificateRequest = factory
				.createMessageContentCertificaterequest();
		certificateRequest.setType(typeCert);
		certificateRequest.setMobile(mobile);

		Content content = this.factory.createMessageContent();
		content.setCertificaterequest(certificateRequest);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageDownload(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, String certificate,
			String typeCert, String mobile) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Download download = factory.createMessageContentDownload();
		download.setCertificate(certificate);
		download.setType(typeCert);
		download.setMobile(mobile);

		Content content = this.factory.createMessageContent();
		content.setDownload(download);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public String createSetiChatMessageUpload(String idSource,
			String idDestination, String idMessage, String type,
			boolean encrypted, boolean signed, String certificate,
			String typeCert) {
		String stringXmlMessage = new String();

		Header header = newInstanceHeader(idSource, idDestination, idMessage,
				type, encrypted, signed);

		Upload upload = factory.createMessageContentUpload();
		upload.setCertificate(certificate);
		upload.setType(typeCert);

		Content content = this.factory.createMessageContent();
		content.setUpload(upload);

		SetiChatMessage message = this.factory.createMessage();
		message.setHeader(header);
		message.setContent(content);

		stringXmlMessage = createXmlString(message);

		return stringXmlMessage;
	}

	/**
	 * 
	 * */
	public Header newInstanceHeader(String idSource, String idDestination,
			String idMessage, String type, boolean encrypted, boolean signed) {
		Header header = this.factory.createMessageHeader();
		header.setIdSource(idSource);
		header.setIdDestination(idDestination);
		header.setIdMessage(idMessage);
		header.setType(type);
		header.setEncrypted(encrypted);
		header.setSigned(signed);
		return header;
	}

	/**
	 * 
	 * */
	public String createXmlString(SetiChatMessage message) {
		ByteArrayOutputStream xmlMessage = new ByteArrayOutputStream();

		try {
			JAXBContext context = JAXBContext
					.newInstance("es.uc3m.setichat.utils.setichatxmlschema");
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE);
			marshaller.marshal(message, xmlMessage);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return xmlMessage.toString();
	}

	/*
	 * *********************************************************************
	 * ***************** DEBUG RAPIDO DE TIPOS DE MENSAJE ******************
	 * *********************************************************************
	 */

	// public static void main(String[] args) throws JAXBException {
	// SetiChatMessageFactory msg = new SetiChatMessageFactory();
	// ArrayList<String> p1 = new ArrayList<String>();
	// p1.add("123456798");
	// p1.add("741852963");
	// ArrayList<String> p2 = new ArrayList<String>();
	// p2.add("dgobiu");
	// p2.add("dsanfoign");
	// String xmlSignUp = msg.createSetiChatMessageSignup("654321987",
	// "setichat83838@appspot.com", "123456789abcdef",
	// String.valueOf(MessageTypeConstants.TYPE_SIGNUP), false, false,
	// "Heaven", "654321987");
	// System.out.println(xmlSignUp);
	// String xmlContactRequest = msg.createSetiChatMessageContactRequest(
	// "654321987", "setichat83838@appspot.com", "123456789abcdef",
	// "2", false, false, p1);
	// System.out.println(xmlContactRequest);
	// String xmlContactResponse = msg.createSetiChatMessageContactResponse(
	// "654321987", "setichat83838@appspot.com", "123456789abcdef",
	// String.valueOf(MessageTypeConstants.TYPE_CONTACTRESPONSE),
	// false, false, p1, p2);
	// System.out.println(xmlContactResponse);
	// String xmlConnect = msg.createSetiChatMessageConnect("654321987",
	// "setichat83838@appspot.com", "123456789abcdef",
	// String.valueOf(MessageTypeConstants.TYPE_CONNECTION), false,
	// false);
	// System.out.println(xmlConnect);
	// String xmlChatMessage = msg.createSetiChatMessageChatMessage(
	// "666666666", "654321987", "123456789abcdef",
	// String.valueOf(MessageTypeConstants.TYPE_CHATMESSAGE), false,
	// false, "Hello world!");
	// System.out.println(xmlChatMessage);
	// String xmlResponse = msg.createSetiChatMessageResponse("a", "b", "c",
	// "d", false, false, ResponseMessageConstants.RESPONSE_CODE_SIGNUP_OK,
	// ResponseMessageConstants.RESPONSE_MESSAGE_SIGNUP_OK);
	// System.out.println(xmlResponse);
	// String xmlRevocation = msg.createSetiChatMessageRevocation("a", "b",
	// "c", "d", false, false, "123456789");
	// System.out.println(xmlRevocation);
	// String xmlCertificateRequest = msg
	// .createSetiChatMessageCertificateRequest("a", "b", "c", "d",
	// false, false, "cer", "123456789");
	// System.out.println(xmlCertificateRequest);
	// String xmlDownload = msg.createSetiChatMessageDownload("a", "b", "c",
	// "d", false, false, "asfbui23", "cer", "123456789");
	// System.out.println(xmlDownload);
	// String xmlUpload = msg.createSetiChatMessageUpload("a", "b", "c",
	// "d",
	// false, false, "asfbui23", "cer");
	// System.out.println(xmlUpload);
	// System.out
	// .println(msg
	// .isSetiChatMessageFormat("<?xml version='1.0' encoding='UTF-8'?><message><header><idSource>+34665432178</idSource><idDestination>setichat@appspot.com</idDestination><idMessage>12345678</idMessage><type>1</type><encrypted>false</encrypted><signed>false</signed></header><content><contactList/></content></message>"));
	// }
}
